class Carousel {
    // 轮播图 最外层元素
    private elem: HTMLElement;
    // 轮播模式
    private mode: string;
    // 轮播内容 父元素
    private carouselWrapper: HTMLElement;
    // 轮播项
    private carouselItems: HTMLCollection;
    // 指示器
    private carouselIndicators: HTMLCollection;
    // 播放速度
    private speed: number;
    // 当前播放第几项
    private currIdx: number = 0;
    private timer: any = null;

    constructor(options) {
        this.elem = document.querySelector(options.elem);
        this.carouselItems = this.elem.getElementsByClassName('carousel-item');
        this.carouselIndicators = this.elem.getElementsByClassName('indicator');
        this.carouselWrapper = this.elem.querySelector('.carousel-wrapper');
        this.mode = options.mode || "fade";
        this.speed = options.speed || 2000;
        this.init();
    }
    // 轮播初始化
    private init() {
        this.autoPlay();
        this.bindEvent();
        this.setMode();
    }
    // 处理事件绑定
    private bindEvent() {
        this.elem.addEventListener('mouseenter', this.handleHover.bind(this), false);
        this.elem.addEventListener('mouseleave', this.handleHover.bind(this), false);
        this.elem.addEventListener('click', this.handleClick.bind(this), false);
    }
    // 设置轮播模式
    private setMode() {
        switch (this.mode) {
            case 'fade':
                this.carouselWrapper.className += ' fade';
                break;
            case 'slider':
                this.carouselWrapper.className += ' slider';
                Array.from(this.carouselItems).map((item: any) => {
                    item.style.width = this.elem.clientWidth + 'px';
                })
                this.carouselWrapper.appendChild(this.carouselItems[0].cloneNode(true));
                this.carouselWrapper.style.width = this.elem.clientWidth * this.carouselItems.length + 'px';
                break;
            default:
                break;
        }
    }
    /**
     * 鼠标移入移除
     * @param e 
     */
    private handleHover(e: MouseEvent) {
        const eventType = e.type;
        switch (eventType) {
            case 'mouseenter':
                clearInterval(this.timer);
                break;
            case 'mouseleave':
                this.autoPlay();
                break;
            default:
                break;
        }
    }
    /**
     * 处理指示器与左右箭头点击事件
     * @param e 
     */
    private handleClick(e: MouseEvent) {
        const ev = e || window.event,
            tar = (ev.target || ev.srcElement) as HTMLElement,
            dataDir = tar.dataset.dir,
            tagName = tar.tagName.toLowerCase();
        switch (tagName) {
            case 'button':
                this.setCurrIdx(dataDir);
                this.pageChange(this.currIdx);
                break;
            case 'i':
                const tarIndex = Array.from(this.carouselIndicators).findIndex((item) => item === tar);
                this.currIdx = tarIndex;
                this.pageChange(this.currIdx);
                break;
            default:
                break;
        }
    }
    /**
     * 自动轮播
     */
    private autoPlay() {
        this.timer = setInterval(this.run.bind(this), this.speed);
    }
    // 轮播
    private run() {
        // 默认next
        this.setCurrIdx('next');
        // 切换
        this.pageChange(this.currIdx);
    }
    // 设置currIdx 
    private setCurrIdx(dir: string) {
        switch (dir) {
            case 'next':
                if (this.mode === 'slider') {
                    if (this.currIdx === this.carouselItems.length - 1) {
                        this.currIdx = 1;
                        this.carouselWrapper.style.transition = 'inherit';
                        this.carouselWrapper.style.transform = 'translateX(0)';
                        const t = setTimeout(() => {
                            this.carouselWrapper.style.transition = 'all .5s';
                            this.carouselWrapper.style.transform = `translateX(-${this.elem.clientWidth * this.currIdx}px)`;
                            clearTimeout(t);
                        }, 1)
                    } else {
                        this.currIdx++;
                        this.carouselWrapper.style.transition = 'all .5s';
                        this.carouselWrapper.style.transform = `translateX(-${this.elem.clientWidth * this.currIdx}px)`;
                    }
                } else if (this.mode === 'fade') {
                    this.currIdx === (this.carouselItems.length - 1) ?
                        this.currIdx = 0 : this.currIdx++;
                }
                break;
            case 'prev':
                if (this.mode === 'slider') {
                    if (this.currIdx === 0) {
                        this.currIdx = this.carouselItems.length - 1;
                        this.carouselWrapper.style.transition = 'inherit';
                        this.carouselWrapper.style.transform = `translateX(-${this.elem.clientWidth * this.currIdx}px)`;
                        this.currIdx = this.currIdx-1;
                        const t1 = setTimeout(() => {
                            this.carouselWrapper.style.transition = 'all .5s';
                            this.carouselWrapper.style.transform = `translateX(-${this.elem.clientWidth * this.currIdx}px)`;
                            clearTimeout(t1);
                        }, 100)
                    } else {
                        this.currIdx--;
                        console.log(this.currIdx);
                        this.carouselWrapper.style.transition = 'all .5s';
                        this.carouselWrapper.style.transform = `translateX(-${this.elem.clientWidth * this.currIdx}px)`;
                    }
                } else if (this.mode === 'fade') {
                    this.currIdx === 0 ?
                        this.currIdx = (this.carouselItems.length - 1) : this.currIdx--;
                }
                break;
            default:
                break;
        }
    }
    // 根据不同模式 处理切换
    private pageChange(index: number): void {
        switch (this.mode) {
            case 'fade':
                this.handleFade(index);
                break;
            case 'slider':
                this.activeItem(this.carouselIndicators, 'indicator', index);
                break;
            default:
        }
    }
    // 处理fade模式 轮播形式
    private handleFade(index: number) {
        this.activeItem(this.carouselItems, 'carousel-item', index);
        this.activeItem(this.carouselIndicators, 'indicator', index);
    }
    /**
     * 设置激活状态
     * @param els 
     * @param className 
     * @param index 
     */
    private activeItem(els: HTMLCollection, className: string, index: number) {
        Array.from(els).map((item) => {
            item.className = className;
        })
        if (index === els.length) {
            index = 0;
        } 
        els[index].className += ' active';
    }

}
export default Carousel;